package com.su.dolphin.control.task;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.annotation.SuppressLint;
import android.os.AsyncTask;
import android.text.TextUtils;

import com.su.dolphin.common.DpAppInfo;
import com.su.dolphin.control.bean.BaseBean;
import com.su.dolphin.utils.LogUtil;

/*
 * Model中的异步的Task, 主要用来处理各种异步操作, 需要配合IModelListener使用, 注意 这个操作的回调是线程安全的
 */
public class CtrlTask extends AsyncTask<Void, Integer, BaseBean> {

    public static ExecutorService LIMITED_TASK_EXECUTOR = (ExecutorService) Executors
            .newFixedThreadPool(5);
    protected static HashMap<String, CtrlTask> TASKS = new HashMap<String, CtrlTask>();

    // set max thread count of the asyncTask = 5
    public IControlResponse mResponse;
    public String mTaskKey;
    public IControlWork mWork;

    /**
     * @title:CtrlTask 注意, 如果使用这个构造函数,无法cancel (等其他控制)指定的task
     */
    public CtrlTask() {
    }

    /**
     * @param taskKey  任务key
     * @param response 返回
     * @param work     任务
     * @title:CtrlTask
     * @description:所有的功能都收敛到这里
     */
    public CtrlTask(String taskKey, IControlResponse response, IControlWork work) {
        if (response != null) {
            mResponse = response;
            if (TextUtils.isEmpty(taskKey)) {
                this.mTaskKey = response.getClass().getName();
            } else {
                this.mTaskKey = taskKey;
            }
            TASKS.put(mTaskKey, this);
        }
        mWork = work;
    }

    public CtrlTask setTaskKey(String taskKey) {
        this.mTaskKey = taskKey;
        TASKS.put(mTaskKey, this);
        return this;
    }

    public CtrlTask setWork(IControlWork mWork) {
        this.mWork = mWork;
        return this;
    }

    public CtrlTask setResponse(IControlResponse response) {
        this.mResponse = response;
        return this;

    }

    @Override
    protected final BaseBean doInBackground(Void... paramArrayOfParams) {
        try {
            // The user did not set Work!
            if (mWork == null) {
                LogUtil.i(mTaskKey + " : mWork is null! Please setWork first!");
                return null;
            } else {
                return mWork.doWork();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 执行Task
     */
    @SuppressLint("NewApi")
    public void exec() {
        if (mWork == null) {
            LogUtil.i(mTaskKey + " : mWork is null! Please setWork first!");
            return;
        }
        LogUtil.i("Running Task ======> " + mTaskKey);
        if (DpAppInfo.PHONE_ANDROID_SDK_INT < 11) {
            execute();
        } else {
            executeOnExecutor(LIMITED_TASK_EXECUTOR);
        }
    }

    /**
     * 任务执行Ok后返回数据
     *
     * @param result
     */
    protected void onPostExecute(BaseBean result) {
        if (result == null) {
            result = new BaseBean(BaseBean.STATUS_FAILED);
        }
        // 使用 try 块防止回调的时候发生崩溃
        try {
            result.setTaskKey(mTaskKey);
            //Fk 如果result = null 都没办法返回了!!
            if (mResponse != null) {
                mResponse.onControlResponse(result);
            }
        } catch (Exception e) {
            e.printStackTrace();
            mResponse.onControlResponse(null);
        }
        TASKS.remove(mTaskKey);
    }

    ;

    @Override
    protected void onCancelled() {
        LogUtil.i("Task: " + mTaskKey + " Has been cancled");
        if (mResponse != null) {
            mResponse.onControlResponse(new BaseBean(BaseBean.CANCELED));
        }
        super.onCancelled();
    }

    // ------------------------各种Task操作---------------------------------------------

    /**
     * 取消所有task
     */
    public static void cancelAllTasks() {
        Iterator<Entry<String, CtrlTask>> iter = TASKS.entrySet().iterator();
        while (iter.hasNext()) {
            Entry<String, CtrlTask> entry = iter.next();
            CtrlTask task = entry.getValue();
            if (task != null) {
                task.cancel(true);
            }
        }
    }

    /**
     * cancel 执行的task
     *
     * @param key task Key
     */
    public static void cancelTask(String key) {
        CtrlTask modelTask = TASKS.get(key);
        if (modelTask != null) {
            if (!modelTask.isCancelled()) {
                modelTask.cancel(true);
                TASKS.remove(modelTask);
            }

        }
    }

    public static CtrlTask getTask(String key) {
        if (TASKS != null) {
            return TASKS.get(key);
        }
        return null;
    }

    public String getTaskKey() {
        return mTaskKey;
    }

    public interface IControlResponse<T extends BaseBean> {
        public void onControlResponse(T data);
    }

    public interface IControlWork {
        public BaseBean doWork();
    }

    public static void submitTask(IControlWork work,
                                  IControlResponse<? extends BaseBean> response) {
        submitTask(null, work, response);
    }

    public static void submitTask(String key, IControlWork work,
                                  IControlResponse<? extends BaseBean> response) {
        new CtrlTask().setTaskKey(key).setWork(work).setResponse(response)
                .exec();
    }
}
